﻿﻿/*
* Introduction：    LoomManager 是一个用于在Unity中实现多线程任务调度和主线程回调的管理器。
                    它允许在子线程中执行任务，并通过队列机制将需要在主线程中执行的操作安全地传递到主线程执行，同时支持延迟执行功能。
* Version：         1.1
* Creator：         yixiang.hui
* Creation Time：   2025.9.3
*
* Last Editor：     yixiang.hui 
* Last Edit Time：  2025.9.3
* Note：            1.1版本添加注释
*/

﻿﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using UnityEngine;

namespace HyxFrame.Core
{
    /// <summary>
    /// 提供多线程任务调度和主线程回调功能的管理器
    /// 使用示例：
    /// Loom.QueueOnMainThread((param) =>
    /// {
    ///     text.text = "";
    /// }, null);
    /// </summary>
    public class LoomManager : MonoSingleton<LoomManager>
    {
        public static int maxThreads = 8; // 最大线程数限制
        static int numThreads; // 当前运行的线程数

        // 非延迟执行的任务结构
        public struct NoDelayedQueueItem
        {
            public Action<object> action; // 要执行的操作
            public object param; // 操作参数
        }

        private List<NoDelayedQueueItem> _actions = new List<NoDelayedQueueItem>(); // 待执行的非延迟任务列表

        // 延迟执行的任务结构
        public struct DelayedQueueItem
        {
            public float time; // 执行时间（Time.time + delay）
            public Action<object> action; // 要执行的操作
            public object param; // 操作参数
        }

        private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>(); // 待执行的延迟任务列表
        List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>(); // 当前帧要执行的延迟任务列表

        protected override void InitManager()
        {
            // 初始化管理器
        }

        /// <summary>
        /// 将任务添加到主线程执行队列（立即执行）
        /// </summary>
        public static void QueueOnMainThread(Action<object> taction, object tparam)
        {
            QueueOnMainThread(taction, tparam, 0f);
        }

        /// <summary>
        /// 将任务添加到主线程执行队列（可延迟执行）
        /// </summary>
        /// <param name="time">延迟时间（秒）</param>
        public static void QueueOnMainThread(Action<object> taction, object tparam, float time)
        {
            if (time != 0)
            {
                lock (Instance._delayed)
                {
                    // 添加延迟任务
                    Instance._delayed.Add(new DelayedQueueItem { 
                        time = Time.time + time, 
                        action = taction, 
                        param = tparam 
                    });
                }
            }
            else
            {
                lock (Instance._actions)
                {
                    // 添加立即执行任务
                    Instance._actions.Add(new NoDelayedQueueItem { 
                        action = taction, 
                        param = tparam 
                    });
                }
            }
        }

        /// <summary>
        /// 在异步线程中执行操作
        /// </summary>
        /// <returns>线程对象</returns>
        public static Thread RunAsync(Action a)
        {
            // 等待直到有可用的线程槽
            while (numThreads >= maxThreads)
            {
                Thread.Sleep(100);
            }
            
            Interlocked.Increment(ref numThreads); // 原子操作增加线程计数
            ThreadPool.QueueUserWorkItem(RunAction, a); // 将任务添加到线程池
            return null;
        }

        // 在线程池中执行操作的包装方法
        private static void RunAction(object action)
        {
            try
            {
                ((Action)action)(); // 执行操作
            }
            catch
            {
                // 忽略异常
            }
            finally
            {
                Interlocked.Decrement(ref numThreads); // 原子操作减少线程计数
            }
        }

        void Start()
        {
            // 初始化
        }

        List<NoDelayedQueueItem> _currentActions = new List<NoDelayedQueueItem>(); // 当前帧要执行的非延迟任务列表

        void Update()
        {
            // 处理非延迟任务
            if (_actions.Count > 0)
            {
                lock (_actions)
                {
                    _currentActions.Clear();
                    _currentActions.AddRange(_actions); // 复制任务到当前列表
                    _actions.Clear(); // 清空原列表
                }
                
                for (int i = 0; i < _currentActions.Count; i++)
                {
                    _currentActions[i].action(_currentActions[i].param); // 执行任务
                }
            }

            // 处理延迟任务
            if (_delayed.Count > 0)
            {
                lock (_delayed)
                {
                    _currentDelayed.Clear();
                    // 筛选出到期的延迟任务
                    _currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time));
                    
                    for (int i = 0; i < _currentDelayed.Count; i++)
                    {
                        _delayed.Remove(_currentDelayed[i]); // 从原列表中移除已处理的任务
                    }
                }

                for (int i = 0; i < _currentDelayed.Count; i++)
                {
                    _currentDelayed[i].action(_currentDelayed[i].param); // 执行到期任务
                }
            }
        }

        protected override void OnApplicationQuit()
        {
            base.OnApplicationQuit();
            // 清理所有任务列表
            _actions.Clear();
            _delayed.Clear();
            _currentDelayed.Clear();
            _currentActions.Clear();
        }

        protected override void OnDestroy()
        {

            base.OnDestroy();
        }

        /* 使用方法示例
        private void test()
        {
            Loom.QueueOnMainThread((param) => { PlayerEntity.Instance.IsGrab = true; }, null);
        }
        */
    }
}